/*
 * Copyright (C) 2020 Graylog, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Server Side Public License, version 1,
 * as published by MongoDB, Inc.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * Server Side Public License for more details.
 *
 * You should have received a copy of the Server Side Public License
 * along with this program. If not, see
 * <http://www.mongodb.com/licensing/server-side-public-license>.
 */
import * as React from 'react';
import { render, screen, within } from 'wrappedTestingLibrary';
import userEvent from '@testing-library/user-event';

import { useQueryParam } from 'routing/QueryParams';
import { MockStore } from 'helpers/mocking';
import asMock from 'helpers/mocking/AsMock';
import useFetchEntities from 'components/common/PaginatedEntityTable/useFetchEntities';
import useUserLayoutPreferences from 'components/common/EntityDataTable/hooks/useUserLayoutPreferences';
import { layoutPreferences } from 'fixtures/entityListLayoutPreferences';
import TestStoreProvider from 'views/test/TestStoreProvider';
import useViewsPlugin from 'views/test/testViewsPlugin';
import IndexSetFieldTypesPage from 'pages/IndexSetFieldTypesPage';
import useFieldTypesForMappings from 'views/logic/fieldactions/ChangeFieldType/hooks/useFieldTypesForMappings';
import { overriddenIndexField, defaultField, attributes } from 'fixtures/indexSetFieldTypes';
import DefaultQueryParamProvider from 'routing/DefaultQueryParamProvider';

const getData = (list = [defaultField]) => ({
  list,
  pagination: {
    total: 1,
  },
  attributes,
});

const renderIndexSetFieldTypesPage = () =>
  render(
    <DefaultQueryParamProvider>
      <TestStoreProvider>
        <IndexSetFieldTypesPage />
      </TestStoreProvider>
      ,
    </DefaultQueryParamProvider>,
  );

jest.mock('views/logic/fieldactions/ChangeFieldType/hooks/useFieldTypesForMappings', () => jest.fn());
jest.mock('components/common/PaginatedEntityTable/useFetchEntities', () => jest.fn());

jest.mock('components/common/EntityDataTable/hooks/useUserLayoutPreferences');
jest.mock('components/perspectives/hooks/useActivePerspective');

jest.mock('routing/QueryParams', () => ({
  ...jest.requireActual('routing/QueryParams'),
  useQueryParam: jest.fn(),
}));

jest.mock('stores/indices/IndexSetsStore', () => ({
  IndexSetsActions: {
    list: jest.fn(() => Promise.resolve()),
    get: jest.fn(() => Promise.resolve()),
  },
  IndexSetsStore: MockStore([
    'getInitialState',
    () => ({
      indexSets: [{ id: '111', title: 'index set title', field_type_profile: null }],
      indexSet: { id: '111', title: 'index set title', field_type_profile: null },
    }),
  ]),
}));

describe('IndexSetFieldTypesPage', () => {
  useViewsPlugin();

  beforeEach(() => {
    asMock(useUserLayoutPreferences).mockReturnValue({
      data: {
        ...layoutPreferences,
        attributes: {
          field_name: { status: 'show' },
          origin: { status: 'show' },
          is_reserved: { status: 'show' },
          type: { status: 'show' },
        },
      },
      isInitialLoading: false,
      refetch: () => {},
    });

    asMock(useFieldTypesForMappings).mockReturnValue({
      data: {
        fieldTypes: {
          string: 'String type',
          int: 'Number(int)',
          bool: 'Boolean',
        },
      },
      isLoading: false,
    });

    asMock(useQueryParam).mockImplementation(() => [undefined, () => {}]);
  });

  it('Shows modal on edit click', async () => {
    asMock(useFetchEntities).mockReturnValue({
      isInitialLoading: false,
      refetch: () => {},
      data: getData([overriddenIndexField]),
    });

    renderIndexSetFieldTypesPage();
    const tableRow = await screen.findByTestId('table-row-field-1');
    const editButton = await within(tableRow).findByText('Edit');
    await userEvent.click(editButton);
    await screen.findByText(/change field-1 field type/i);
    const modal = await screen.findByRole('dialog', { name: /Change field-1 Field Type/i });
    await within(modal).findByText('Boolean');

    expect(within(modal).queryByText(/select targeted index sets/i)).not.toBeInTheDocument();
  });

  it('Shows modal on Change field type click', async () => {
    asMock(useFetchEntities).mockReturnValue({
      isInitialLoading: false,
      refetch: () => {},
      data: getData([overriddenIndexField]),
    });

    renderIndexSetFieldTypesPage();
    const editButton = await screen.findByRole('button', { name: /change field type/i });
    await userEvent.click(editButton);

    const modal = await screen.findByRole('dialog', { name: /change field type/i });
    await within(modal).findByRole('heading', { name: /change field type/i });
    await within(modal).findByText(/select or type the field/i);

    expect(within(modal).queryByText(/select targeted index sets/i)).not.toBeInTheDocument();
  });
});
